import CryptoJS from 'crypto-js';
import smCrypto, { CipherMode } from 'sm-crypto';

// -----------------------  AES 加密、解密 -----------------------
/**
 * AES 加密、解密
 */
export const AES = {
  /** AES 加密 */
  encrypt: function (data: any, aes_key = '') {
    // AES 加密 并转为 base64
    let utf8Data = CryptoJS.enc.Utf8.parse(object2string(data));
    const key = CryptoJS.enc.Utf8.parse(aes_key);
    const encrypted = CryptoJS.AES.encrypt(utf8Data, key, {
      mode: CryptoJS.mode.ECB,
      padding: CryptoJS.pad.Pkcs7,
    });

    return encrypted.toString();
  },

  /** AES 解密 */
  decrypt: function (cipherText: string, aes_key = '') {
    //  第一步：Base64 解码
    // let keyBytes = CryptoJS.enc.Utf8.parse(aes_key);
    // 第三步：AES 解密
    const key = CryptoJS.enc.Utf8.parse(aes_key);
    return CryptoJS.AES.decrypt(cipherText, key, {
      mode: CryptoJS.mode.ECB,
      padding: CryptoJS.pad.Pkcs7,
    }).toString(CryptoJS.enc.Utf8);
  },
};

// -----------------------  国密SM4算法 加密、解密 -----------------------

const sm2 = smCrypto.sm2;
const sm3 = smCrypto.sm3;
const sm4 = smCrypto.sm4;
const defaultCipherMode = 1; // 1 - C1C3C2，0 - C1C2C3，默认为1
const defaultPublicKey = '';
const defaultPrivateKey = '';
const defaultVi = 'fedcba98765432100123456789abcdef';
const defaultKey = '';

/**
 * 国密SM算法 加密、解密
 */
export const CryptoSM = {
  doSm2Encrypt: function (
    msgString: string | ArrayLike<number>,
    publicKey = defaultPublicKey,
    cipherMode: CipherMode = defaultCipherMode,
  ) {
    return sm2.doEncrypt(msgString, publicKey, cipherMode);
  },
  // SM2解密
  doSm2Decrypt: function (
    encryptData: string,
    privateKey = defaultPrivateKey,
    cipherMode: CipherMode = defaultCipherMode,
  ) {
    return sm2.doDecrypt(encryptData, privateKey, cipherMode);
  },
  // SM2数组加密
  doSm2ArrayEncrypt: function (
    msgString: string | ArrayLike<number>,
    publicKey = defaultPublicKey,
    cipherMode: CipherMode = defaultCipherMode,
  ) {
    return sm2.doEncrypt(msgString, publicKey, cipherMode);
  },
  // SM2数组解密
  doSm2ArrayDecrypt: function (
    encryptData: string,
    privateKey = defaultPrivateKey,
    cipherMode: CipherMode = defaultCipherMode,
  ) {
    return sm2.doDecrypt(encryptData, privateKey, cipherMode, { output: 'array' });
  },
  // SM3哈希
  doSm3Hash: function (msgString: string | ArrayLike<number>) {
    return sm3(msgString);
  },
  // SM4 加密
  doSm4Encrypt: function (msgString: string | number[], key = defaultKey) {
    return sm4.encrypt(msgString, key);
  },
  // SM4 解密
  doSm4Decrypt: function (encryptData: string | number[], key = defaultKey) {
    return sm4.decrypt(encryptData, key);
  },
  // SM4 CBC加密
  doSm4CbcEncrypt: function (msgString: string | number[], key = defaultKey, iv = defaultVi) {
    return sm4.encrypt(msgString, key, { mode: 'cbc', iv: iv }); // 加密，cbc模式
  },
  // SM4 CBC解密
  doSm4CbcDecrypt: function (encryptData: string | number[], key = defaultKey, iv = defaultVi) {
    return sm4.decrypt(encryptData, key, { mode: 'cbc', iv: iv }); // 加密，cbc模式
  },
};

// -----------------------  其他工具 -----------------------

/** 转为字符串 */
export const object2string = (data: any) => {
  if (data === null) {
    return '';
  }
  if (typeof data === 'object') {
    return JSON.stringify(data);
  }

  let str = JSON.stringify(data);
  if (str.startsWith("'") || str.startsWith('"')) {
    str = str.substring(1);
  }
  if (str.endsWith("'") || str.endsWith('"')) {
    str = str.substring(0, str.length - 1);
  }
  return str;
};
